/*
 * To change this template, choose Tools | Templates and open the template in
 * the editor.
 */
package BESA.Mobile;

import BESA.Config.ConfigBESA;
import BESA.ExceptionBESA;
import BESA.Extern.ExternAdmBESA;
import BESA.Kernell.Agent.AgentBESA;
import BESA.Kernell.Agent.StateBESA;
import BESA.Kernell.Agent.StructBESA;
import BESA.Kernell.System.Directory.AgHandlerBESA;
import BESA.Kernell.System.SystemExceptionBESA;
import BESA.Log.ReportBESA;
import BESA.Mobile.Directory.AgMobilelHandlerBESA;
import BESA.PostOffice.CommunicationChannel.Types.Socket.ServerSocket_BPO;
import BESA.PostOffice.Message.MessageFactory_BPO;
import BESA.PostOffice.PostOffice_BPO;
import BESA.Remote.DistributedExceptionBESA;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 */
public class MobileAdmBESA extends ExternAdmBESA{ //implements IMobileAdmBESA {

    private final int ATTEMPS = 7;
    private final int DEFAULT_PORT = 8000;

    public MobileAdmBESA(ConfigBESA configBESA) throws DistributedExceptionBESA {
        super(configBESA);
        INSTANCE = this;
        try {
            PostOffice_BPO.get().addServerListener(new ServerSocket_BPO(DEFAULT_PORT));
        } catch (IOException ex) {
            ReportBESA.error(ex);
        }
    }

    /**
     * 
     * @param agAlias
     * @return
     * @throws ExceptionBESA
     */
    @Override
    public AgHandlerBESA getHandlerByAlias(String agAlias) throws ExceptionBESA {
        AgHandlerBESA ah = null;
        try {
            ah = super.getHandlerByAlias(agAlias);
            return ah;
        } catch (Exception ex) {
            //PostOffice_BPO.get().sendMessageToLocation("", MessageFactory_BPO.lookupAgentCreatedMessage(agAlias));
            //------------------------------------------------------------//
            // Doc...
            //------------------------------------------------------------//
            int cont = 0;
            while (cont < ATTEMPS) {
                try {
                    cont++;
                    Thread.sleep(1000);
                    ah = localDirectory.getHandlerByAlias(agAlias);
                    if (ah != null) {
                        return ah;
                    }
                } catch (InterruptedException ex1) {
                    ReportBESA.error(ex1);
                }
            }
        }
        //----------------------------------------------------------------//
        // 
        //----------------------------------------------------------------//
        throw new SystemExceptionBESA("Agent with alias: " + agAlias + ", not found.");
    }

    /**
     * 
     * @param agAlias
     * @param agId
     * @param containerID
     */
    //@Override
    public void registerAgentFromMobileDevice(String agAlias, String agId, String containerID) {
        try {
            AgMobilelHandlerBESA agMobilelHandlerBESA = new AgMobilelHandlerBESA(agId, agAlias, containerID);
            super.registerAgent(agId, agMobilelHandlerBESA, agAlias);
            super.publicagent(agAlias, agId);
        } catch (SystemExceptionBESA ex) {
            ReportBESA.error(ex);
        }
    }

    //@Override
    public void eliminateAgentFromMobileDevice(String agId) {
        try {
            super.unregisterAgent(agId);
        } catch (SystemExceptionBESA ex) {
            ReportBESA.error(ex);
        }
    }

    //@Override
    public void moveAgentFromMobileDevice(String aliasDestinationAdmBESA, String aliasAg, StateBESA stateAg, StructBESA structAg, double passwdAg, String nameClassAgent) {
        try {
            if (!this.getAdmHandler().getAlias().equals(aliasDestinationAdmBESA)) {
                try {
                    //--------------------------------------------------------//
                    //
                    //--------------------------------------------------------//
                    Class cls = Class.forName(nameClassAgent);
                    Class[] partypes = new Class[4];
                    partypes[0] = aliasAg.getClass();
                    partypes[1] = StateBESA.class;//stateAg.getClass();
                    partypes[2] = structAg.getClass();
                    //Double password = new Double(passwdAg);
                    partypes[3] = double.class;//password.getClass();
                    Constructor ct = cls.getConstructor(partypes);
                    //--------------------------------------------------------//
                    //
                    //--------------------------------------------------------//
                    Object[] arglist = new Object[4];
                    arglist[0] = aliasAg;
                    arglist[1] = (StateBESA) stateAg;
                    arglist[2] = structAg;
                    arglist[3] = passwdAg;//new Double(passwdAg);
                    Object agent = ct.newInstance(arglist);
                    //--------------------------------------------------------//
                    //
                    //--------------------------------------------------------//
                    ((AgentBESA) agent).start();
                } catch (Exception e) {
                    ReportBESA.error("Couldn't create a instance of the agent that is moving: " + e.toString());
                    throw new ExceptionBESA("Couldn't create a instance of the agent that is moving: " + e.toString());
                }
            } else {
                super.moveAgent(aliasAg, aliasDestinationAdmBESA, passwdAg);
            }
        } catch (ExceptionBESA ex) {
            ex.printStackTrace();
        }
    }

    //@Override
    public void lookupAgent(String agAlias) {
        try {
            AgHandlerBESA agHandlerBESA = getHandlerByAlias(agAlias);
            //PostOffice_BPO.get().sendMessageToLocation("", MessageFactory_BPO.agentFoundMessage(agHandlerBESA.getAgId(), agAlias, getAdmHandler().getAlias()));
        } catch (ExceptionBESA ex) {
            ReportBESA.error(ex);
        }
    }

    //@Override
    public void agentFound(String agId, String agAlias, String containerID) {
        AgMobilelHandlerBESA agMobilelHandlerBESA = new AgMobilelHandlerBESA(agId, agAlias, containerID);
        super.registerAgent(agId, agMobilelHandlerBESA, agAlias);
        try {
            super.publicagent(agAlias, agId);
        } catch (SystemExceptionBESA ex) {
            ReportBESA.error(ex);
        }
    }
}
